package main

import (
	"fmt"
	"reflect"
	"strconv"
)

type User struct {
	Name string
	Age int
	Sex string
}

func (user User)Say(msg string) error {
	fmt.Println("say:", msg)
	return nil
}

func (user User)Increse(a int)  {
	a++
	fmt.Println(a)
}

func main() {
	user := User{"花花", 18, "女"}

	for {
		fmt.Println("请输入User的方法名")
		method := ""
		fmt.Scanln(&method)

		rValue := reflect.ValueOf(user)
		rType := reflect.TypeOf(user)

		//获取需要调用的方法
		rMethod:=rValue.MethodByName(method)
		fmt.Println(rMethod)
		//判断该方法是否存在
		if !rMethod.IsValid() {
			fmt.Println("该方法不存在")
			continue
		}

		//设置arg适应各种类型的参数
		arg := ""
		fmt.Scanln(&arg)

		//调用函数的入参,需要适配多种类型的数据
		var argValue []reflect.Value
		tMethod,_ := rType.MethodByName(method)

		for i:=1; i<= tMethod.Type.NumIn(); i++ {

		}
		//需要获取函数的参数
		var inputArg interface{}

		switch tMethod.Type.In(1).Kind() {
		case reflect.String:
			inputArg = arg
		case reflect.Int:
			inputArg , _ = strconv.Atoi(arg)
		case reflect.Float64:
			inputArg , _ = strconv.ParseFloat(arg, 64)
		default:
			fmt.Println("类型不对1")
		}



		argValue := []reflect.Value{reflect.ValueOf(inputArg)}
		rMethod.Call(argValue)
	}
}
